package SimpleCreatorFacotry;

use Signature;
use ICreator;
use TinyMessage;

sub new {
	return bless {}, shift;
}

#
# FIXME: я должен делать копии moduleClasses и classes,
# т.к. я могу создать не нужные креаторы.
# либо вообще нужно пересмотреть место хранения креаторов
#
sub matchCtor {
	my ($cclass, $ctor, $module) = @_;
	
#	if (signature($cclass) =~ m/mapcontext/i) {
#		print "Ok, lets try\n";
#	}
	
	my $classes = $module->project()->classes();
	
	foreach my $carg (@{ $ctor->args() }) {
		if ($carg->type() ne '*' && $carg->type() ne '&') {
			return 0;
		}
		
		my $class_sig = $carg->to_class();

		my $provider = $module->class_provider($class_sig);
		
		if ($provider) {
			next;
		}
		
		my $class = $module->moduleClasses()->value($class_sig);
		
		if ($class) {
			next if ($class->{creator});
			next if (spawnCreator($class, $module->moduleClasses(), $classes));
		}
		
		$class = $classes->value($class_sig);		 
		
		if ($class) {
			fatal 'F_INTERNAL', "Class already have creator, it`s logic error " . signature($class) if ($class->{creator}); #logic error
			$class = $class->clone();
			if (spawnCreator($class, $module)) {
				$module->moduleClasses()->put($class);
				next;			
			}	
			return 0;
		}
		
		return 0;
	}
	
	$cclass->{creator} = new ICreator($cclass, $ctor);
	
	return 1;
}

sub spawnCreator {
	my ($this, $cclass, $module) = ();
	
	if (@_ == 3) {
		($this, $cclass, $module) = @_; 
	} else {
		($cclass, $module) = @_;
	}
	
	foreach my $ctor ($cclass->constructors()) {
		next if (!$ctor->visible());
		
		if (matchCtor($cclass, $ctor, $module)) {
			return 1;
		}
	}
	
	return 0;
}

1;